package com.meida.module.arc.provider.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.meida.common.base.constants.CommonConstants;
import com.meida.common.base.entity.EntityMap;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaDelete;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.utils.DateUtils;
import com.meida.module.admin.client.entity.BaseUser;
import com.meida.module.admin.provider.service.BaseUserService;
import com.meida.module.arc.client.entity.ArcInfo;
import com.meida.module.arc.client.entity.ArcInfoRemind;
import com.meida.module.arc.provider.mapper.ArcInfoRemindMapper;
import com.meida.module.arc.provider.service.ArcInfoRemindService;
import com.meida.module.arc.provider.service.ArcInfoService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 档案到期提醒接口实现类
 *
 * @author flyme
 * @date 2023-07-24
 */
@Service
@Transactional(rollbackFor = Exception.class)
@AllArgsConstructor
@DS("sharding")
public class ArcInfoRemindServiceImpl extends BaseServiceImpl<ArcInfoRemindMapper, ArcInfoRemind> implements ArcInfoRemindService {

    final BaseUserService baseUserService;

    final ArcInfoService arcInfoService;


    @Override
    public ResultBody beforeAdd(CriteriaSave cs, ArcInfoRemind air, EntityMap extra) {

        setData(air);

        return ResultBody.ok();
    }

    @Override
    public ResultBody afterAdd(CriteriaSave cs, ArcInfoRemind arcInfoRemind, EntityMap extra) {
        long l = arcInfoRemind.getRemindDate().getTime() - System.currentTimeMillis();
        //mqTemplate.sendMessage(QueueConstants.QUEUE_REMIND, arcInfoRemind.getRemindId(), Integer.valueOf(l + ""));

        redisUtils.set("infoRemind:" + arcInfoRemind.getRemindId(), arcInfoRemind.getRemindId(), l / 1000);
        arcInfoService.update(new UpdateWrapper<ArcInfo>().lambda().eq(ArcInfo::getCategoryId, arcInfoRemind.getCategoryId()).eq(ArcInfo::getQzId, arcInfoRemind.getQzId()).eq(ArcInfo::getArcInfoId, arcInfoRemind.getArcInfoId()).set(ArcInfo::getIsRemind, 1));
        return super.afterAdd(cs, arcInfoRemind, extra);
    }


    private void setData(ArcInfoRemind air) {
        String remindDay = air.getRemindDay();
        int remindType = air.getRemindType();
        String remindTime = air.getRemindTime();
        String date = remindDay + " " + remindTime;

        DateTime dateTime = DateUtil.parse(date, "yyyy-MM-dd HH:mm");
        if (remindType > 4) {
            dateTime = DateUtil.offsetMonth(DateUtil.parse(date, "yyyy-MM-dd HH:mm"), 4 - remindType);
        } else if (remindType == 3 || remindType == 4) {
            dateTime = DateUtil.offsetWeek(DateUtil.parse(date, "yyyy-MM-dd HH:mm"), 2 - remindType);
        } else if (remindType == 1 || remindType == 2) {
            dateTime = DateUtil.offsetDay(DateUtil.parse(date, "yyyy-MM-dd HH:mm"), 0 - remindType);
        }
        air.setRemindDate(dateTime);
        air.setReadState(CommonConstants.INT_0);
    }


    @Override
    public ResultBody beforeEdit(CriteriaUpdate<ArcInfoRemind> cu, ArcInfoRemind arcInfoRemind, EntityMap extra) {
        setData(arcInfoRemind);
        return super.beforeEdit(cu, arcInfoRemind, extra);
    }

    @Override
    public ResultBody afterEdit(CriteriaUpdate cu, ArcInfoRemind arcInfoRemind, EntityMap extra) {
        long l = arcInfoRemind.getRemindDate().getTime() - System.currentTimeMillis();
        //mqTemplate.sendMessage(QueueConstants.QUEUE_REMIND, arcInfoRemind.getRemindId(), Integer.valueOf(l + ""));
        redisUtils.set("infoRemind:" + arcInfoRemind.getRemindId(), arcInfoRemind.getRemindId(), l / 1000);
        return super.afterEdit(cu, arcInfoRemind, extra);
    }

    @Override
    public ResultBody saves(Map params) {

        ArcInfoRemind remind = JSON.parseObject(JSONUtil.toJsonStr(params), ArcInfoRemind.class);

        List<String> split = StrUtil.split(remind.getRemindUserIds(), ',');
        String remindDay = remind.getRemindDay();
        int remindType = remind.getRemindType();
        String remindTime = remind.getRemindTime();
        String date = remindDay + " " + remindTime;

        DateTime dateTime = DateUtil.parse(date, "yyyy-MM-dd HH:mm");
        if (remindType > 4) {
            dateTime = DateUtil.offsetMonth(DateUtil.parse(date, "yyyy-MM-dd HH:mm"), 4 - remindType);
        } else if (remindType == 3 || remindType == 4) {
            dateTime = DateUtil.offsetWeek(DateUtil.parse(date, "yyyy-MM-dd HH:mm"), 2 - remindType);
        } else if (remindType == 1 || remindType == 2) {
            dateTime = DateUtil.offsetDay(DateUtil.parse(date, "yyyy-MM-dd HH:mm"), 0 - remindType);
        }
        List<ArcInfoRemind> list = new ArrayList<>();
        for (String s : split) {
            ArcInfoRemind infoRemind = new ArcInfoRemind();
            BeanUtil.copyProperties(remind, infoRemind);
            //infoRemind.setRemindUserId(Long.valueOf(s));
            infoRemind.setRemindDate(dateTime);
            infoRemind.setReadState(CommonConstants.INT_0);
            list.add(infoRemind);
        }
        // TODO 延时队列发消息
        return ResultBody.ok(this.saveBatch(list));
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<ArcInfoRemind> cq, ArcInfoRemind air, EntityMap requestMap) {
        cq.orderByDesc("air.createTime");
        return ResultBody.ok();
    }

    @Override
    public ResultBody beforeGet(CriteriaQuery<ArcInfoRemind> cq, ArcInfoRemind arcInfoRemind, EntityMap requestMap) {
        cq.eq("arcInfoId", requestMap.getLong("arcInfoId"));
        cq.eq("categoryId", requestMap.getLong("categoryId"));
        cq.eq("qzId", requestMap.getLong("qzId"));
        return ResultBody.ok();

    }

    @Override
    public void afterGet(CriteriaQuery cq, EntityMap result) {
        if (FlymeUtils.isNotEmpty(result)) {
            String remindUserIds = result.get("remindUserIds");
            if (FlymeUtils.isNotEmpty(remindUserIds)) {
                List<BaseUser> byUserIds = baseUserService.findByUserIds(StrUtil.split(remindUserIds, ','));
                result.put("user", byUserIds);
            } else {
                result.put("user", Arrays.asList());

            }
        }

    }


    @Override
    public ResultBody beforeDelete(CriteriaDelete<ArcInfoRemind> cd) {
        Long idValue = cd.getIdValue();
        ArcInfoRemind remind = getOne(new QueryWrapper<ArcInfoRemind>().eq("id", idValue).eq("to_days(remindDate)", DateUtils.toDays()));
        // TODO 延时队列发消息 删除
        if (remind != null) {
            redisUtils.del("infoRemind:" + remind.getRemindId());
        }
        return ResultBody.ok();
    }

    @Override
    public Long getArcInfoCollect(Long arcInfoId) {

        return this.count(new QueryWrapper<ArcInfoRemind>().lambda().eq(ArcInfoRemind::getArcInfoId, arcInfoId));
    }
}
